package com.ly.common.core.tool.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * 自定义密码验证
 *
 * @author luoyun
 * @Date: 2025/7/01 0:46
 * @Note:
 */
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) {
        String username = authentication.getName();
        String rawPassword = authentication.getCredentials().toString();
        // 1. 加载用户
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        // 2. 自定义密码验证逻辑（如动态规则）
        if (!customPasswordCheck(rawPassword, userDetails.getPassword())) {
            throw new BadCredentialsException("密码验证失败");
        }
        // 3. 返回认证成功的 Authentication 对象
        return new UsernamePasswordAuthenticationToken(
                userDetails,
                rawPassword,
                userDetails.getAuthorities()
        );
    }

    /**
     * 自定义密码验证
     *
     * @param rawPassword
     * @param encodedPassword
     * @return
     */
    private boolean customPasswordCheck(String rawPassword, String encodedPassword) {
        // 实现自定义验证逻辑（如调用外部服务）
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
